﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Diagnostics;
using System.Reflection;

namespace IVisual._SC
{
    /// <summary>
    /// Stellt Methoden für das lokale Logging zu Verfügung
    /// </summary>
    public class cls_LOG
    {
        /// <summary>
        /// LOG-Level. Alle niedrigeren Levels werden eingeschlossen!
        /// </summary>
        public enum LOGLEVEL
        {
            ALL = 50,
            METHOD_INVOKE = 40,

            DEBUG = 30,
            INFO = 20,
            ERROR = 10,
            NONE = 0
        }
        
        public static LOGLEVEL LOG_LEVEL = LOGLEVEL.NONE;

        private static bool _HTML = true;
        public static bool HTML
        {
            set
            {
                try
                {
                    _FS.Close();
                }
                catch (Exception) { }

                _FS = null;
                _HTML = value;
            }
            get
            {
                return _HTML;
            }
        }

        private const int _LEN = 80;
        private const char _FZ = ' ';

        private static System.IO.StreamWriter _FS = null;

        /// <summary>
        /// Speichert eine LOG-Zeile
        /// </summary>
        /// <param name="LEVEL">Level des Eintrags</param>
        /// <param name="text">Text des Eintrags</param>
        [System.Diagnostics.DebuggerNonUserCode()]
        public static void WRITE_LOG_LINE(LOGLEVEL LEVEL, string text)
        {
            try
            {
                // Wenn der eintrag ein höres Level hat als eingestellt, abbrechen
                if (LEVEL > cls_LOG.LOG_LEVEL)
                    return;

                // Wenn noch keine File vorhanden ist, eine anlegen
                if ((_FS == null))
                {
                    string FN = System.IO.Path.GetDirectoryName(System.Environment.GetEnvironmentVariable("appdata")) + "\\RM_Neuro_" + System.Windows.Forms.Application.ProductName + "_LOG.html";
                    if (System.Security.Principal.WindowsIdentity.GetCurrent().IsSystem)
                        FN = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\RM_Neuro_" + System.Windows.Forms.Application.ProductName + "_LOG.html";

                    System.IO.File.Delete(FN);
                    _FS = new System.IO.StreamWriter(FN, true, System.Text.Encoding.Default);

                    if(_HTML)
                        _FS.WriteLine("<html><body><table border='1'><tr><th>Product Name</th><th>LEVEL</th><th>Zeitstempel</th><th>Klasse</th><th>Methodenname</th><th>Beschreibung</th></tr>");
                    else
                    {
                        string[] _TITLE = { "Product Name", "LEVEL", "Zeitstempel", "Klasse", "Methodenname", "Beschreibung" };
                        string txt = "";
                        for (int i = 0; i < _TITLE.Length; i++)
                            txt += _TITLE[i].PadRight(_LEN, _FZ);
                        _FS.WriteLine(txt);
                    }
                }

                string praefix = System.Windows.Forms.Application.ProductName + " - " + System.Windows.Forms.Application.ProductVersion;

                if (text == "start")
                {
                    text = "Methode gestartet";
                }
                else if (text == "ende")
                {
                    text = "Methode beendet";
                }
                else
                {
                    // zeichen escapen
                    for (int i = 1; i <= 4; i++)
                    {
                        text = text.Replace(Convert.ToChar(i).ToString(), " | ");
                    }
                }

                StackTrace stackTrace = new StackTrace();
                StackFrame stackFrame = stackTrace.GetFrame(1);
                MethodBase methodBase = stackFrame.GetMethod();

                string pre_call_method_name = "";
                if (stackTrace.FrameCount >= 3)
                    pre_call_method_name = stackTrace.GetFrame(2).GetMethod().ReflectedType.Name + "." + stackTrace.GetFrame(2).GetMethod().Name;

                //HTML-Zeile ablegen
                if (_HTML)
                    _FS.WriteLine("<tr><td>" + praefix + "</td><td>" + LEVEL.ToString("G") + "</td><td>" + DateTime.Now.ToLongTimeString() + ":" + DateTime.Now.Millisecond + "</td><td>" + methodBase.ReflectedType.Name + "</td><td>" + methodBase.ToString() + " (" + pre_call_method_name + ")</td><td>" + text + "</td></tr>");
                else
                    _FS.WriteLine(praefix.PadRight(_LEN, _FZ) + LEVEL.ToString("G").PadRight(_LEN, _FZ) + (DateTime.Now.ToLongTimeString() + ":" + DateTime.Now.Millisecond).PadRight(_LEN, _FZ) + methodBase.ReflectedType.Name.PadRight(_LEN, _FZ) + (methodBase.ToString() + " (" + pre_call_method_name + ")").PadRight(_LEN, _FZ) + text.PadRight(_LEN, _FZ));
                _FS.Flush();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}